package edu.hznu.retroSnakerPlanServer.utils;

import edu.hznu.retroSnakerPlanServer.dto.ResponseMsg;
import edu.hznu.retroSnakerPlanServer.entity.Food;
import edu.hznu.retroSnakerPlanServer.entity.ReqType;
import edu.hznu.retroSnakerPlanServer.entity.SnakeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * create by Cliven on 2018-05-31 21:50
 *
 * @author Cliven
 * 解析构造一个响应字节串
 */
public class ResponseEncode {

    private static final Logger log = LoggerFactory.getLogger(ResponseEncode.class);

    /**
     * 编码实体
     *
     * @param responseMsg 响应实体
     * @return 实体序列化后的字节数组
     * @author Cliven
     * @since 2018-06-01 09:13:52
     */
    public static Byte[] encode(ResponseMsg responseMsg) {
        if (responseMsg == null) {
            throw new IllegalArgumentException("responseMsg 为空");
        }
        LinkedList<Byte> responseData = new LinkedList<>();

        responseData.addLast((byte) (responseMsg.getResType() & 0xFF));
        responseData.addLast((byte) (responseMsg.getMsgCnt() & 0xFF));
        responseData.addLast((byte) (responseMsg.getId() & 0xFF));
        responseData.addLast((byte) (responseMsg.getScore() & 0xFF));
        // 如果是死亡响应包，那么直接响应数据，不在继续解析
        if (ReqType.DEAD.equals(responseMsg.getResType())) {
            return responseData.toArray(new Byte[0]);
        }

        // 获取玩家长度
        Integer playersInfoLen = responseMsg.getPlayersInfoLen();

        // 低位
        responseData.addLast((byte) (playersInfoLen & 0xFF));
        responseData.addLast((byte) ((playersInfoLen >> 8) & 0xFF));
        // 高位
        responseData.addLast((byte) ((playersInfoLen >> 16) & 0xFF));
        responseData.addLast((byte) ((playersInfoLen >> 24) & 0xFF));

        // 遍历所有玩家
        for (List<SnakeNode> player :
                responseMsg.getPlayersInfo()) {
            // 遍历玩家的节点
            for (SnakeNode snakeNode : player) {
                responseData.addAll(Arrays.asList(snakeNode.serial()));
            }
        }

        // 获取食物信息长度
        Integer foodsLen = responseMsg.getFoodsLen();

        // 低位
        responseData.addLast((byte) (foodsLen & 0xFF));
        responseData.addLast((byte) ((foodsLen >> 8) & 0xFF));
        // 高位
        responseData.addLast((byte) ((foodsLen >> 16) & 0xFF));
        responseData.addLast((byte) ((foodsLen >> 24) & 0xFF));

        // 复制食物数组
        for (Food food : responseMsg.getFoods()) {
            responseData.addAll(Arrays.asList(food.serial()));
        }
//        log.debug("ResponseMsg Bytes:{}", ByteUtils.bytesToHex(responseData.toArray(new Byte[0])));
        return responseData.toArray(new Byte[0]);
    }
}
